<script>
/*snakerflow相关*/
//import LogicFlow from '@logicflow/core'
import PropertySetting from './PropertySetting/index.vue'

import { ref } from 'vue'
import LogicFlow from '@logicflow/core'
//import { ElMessage } from 'element-plus'
import { BpmnElement, SelectionSelect, DndPanel ,Menu} from '@logicflow/extension'
import '@logicflow/core/dist/style/index.css'
import '@logicflow/extension/lib/style/index.css'
import { queryFlow, createFlow, saveFlow, deployFlow } from '@/api/turboflow/flow'
import turboAdapter from './turboAdapter'
import Toolbar from './Toolbar.vue'
import Clipboard from "clipboard";
import {Message} from "element-ui";

const CALLER = 'TEST_CALLER'
const TENANT = 'TEST_TENANT'

export default {
  data() {
    return {
      count: 0,
      flowName: '流程',
      flowKey: '',
      activeData: null,
      openDrawer: false,
      drawType: '',
      graphData: '',
      /*snakerflow*/
      lf: null,
      extendAttrConfig: null,
      nodeClick: null,
      dialogTitle: '',
      dialogVisible: false,
      dialogType: 'DataDetail',
      clipboard: null,
      processForm: {},
      refreshLfData: 1
    }},
  async mounted() {
    let flowModuleId = this.$route.params.flowModelId
    if (!flowModuleId) {
      flowModuleId = await this.createFlow()
    }
    this.flowModuleId = flowModuleId;
    await this.queryFlow()
    this.lf = new LogicFlow({
      container: this.$refs.container,
      grid: {
        visible: true,
        type: 'mesh',
        size: 10,
        config: {
          color: '#eeeeee'
        }
      },
      // adjustEdge: false,
      hoverOutline: false,
      edgeSelectedOutline: false,
      keyboard: {
        enabled: true,
      },
      // keyboard: true,
      plugins: [
        // NodeRedExtension,
        BpmnElement,
        SelectionSelect,
        DndPanel,
        Menu,
        turboAdapter,
      ]
    });

    this.lf.extension.dndPanel.setPatternItems([
      {
        label: '选区',
        icon: '',
        callback: () => {
          this.lf.extension.selectionSelect.openSelectionSelect();
          this.lf.once('selection:selected', () => {
            this.lf.extension.selectionSelect.closeSelectionSelect();
          });
        }
      },
      {
        type: 'bpmn:startEvent',
        text: '开始',
        label: '开始节点',
        properties: {},
        icon: '',
      },
      {
        type: 'bpmn:userTask',
        label: '用户任务',
        properties: {},
        icon: '',
      },
      {
        type: 'bpmn:exclusiveGateway',
        label: '条件判断',
        properties: {},
        icon: '',
      },
      {
        type: 'bpmn:endEvent',
        text: '结束',
        label: '结束节点',
        properties: {},
        icon: '',
      }
    ]);
    // 设置右键菜单
    /*this.lf.extension.menu.addMenuConfig({
    });*/
    this.lf.render(this.flowModel || {});
    /*this.lf.extension.menu.setMenuConfig({
      nodeMenu: [
        {
          text: '删除',
          callback(node) {
            debugger
            lf.deleteNode(node.id);
          },
        },
      ], // 覆盖默认的节点右键菜单
      edgeMenu: false, // 删除默认的边右键菜单
      graphMenu: [],  // 覆盖默认的边右键菜单，与false表现一样
    });*/
    //流程属性
    this.lf.on('blank:contextmenu', (args) => {
      this.nodeClick = {
        id: this.processForm.id,
        displayName: this.processForm.displayName,
        expireTime: this.processForm.expireTime,
        instanceUrl: this.processForm.instanceUrl,
        instanceNoClass: this.processForm.instanceNoClass,
        type: 'bpmn:process'
      }
      this.$nextTick(() => {
        this.$refs.propertySetting.show()
      });
    });
    //边单击
    this.lf.on('edge:click', (args ) => {
      this.nodeClick = args.data
      this.$nextTick(() => {
        this.$refs.propertySetting.show()
      });
    });
    //节点点击
    this.lf.on('node:click', (args) => {
      this.extendAttrConfig = 'bpmn:startEvent';
      //this.initProcessForm();
      this.nodeClick = args.data
      this.$nextTick(() => {
        this.$refs.propertySetting.show()
      });
    });
    // 设置右键菜单
    this.lf.on('node:contextmenu,edge:contextmenu', (args) => {
    });
  },
  methods: {
    async createFlow () {
      return new Promise((resolve) => {
        createFlow({
          caller: CALLER,
          flowKey: "flowKey1",
          flowName: this.flowName,
          tenant: TENANT
        }).then(({ data, errCode }) => {
          if (errCode === 1000) {
            const { flowModuleId } = data;
            resolve(flowModuleId);
          }
        })
      })
    },
    async queryFlow() {
      return new Promise((resolve) => {
        queryFlow({
          flowModuleId: this.flowModuleId,
          // flowModuleId: '611a51d8-b199-11ec-bbbf-bec61a540123',
          // flowDeployId: "836fb274-b19d-11ec-be16-bec61a540123"
        }).then(({ data, errCode }) => {
          if (errCode === 1000) {
            const { flowModel, flowName, flowKey } = data;
            if (flowModel) {
              this.flowModel = JSON.parse(flowModel)
            } else {
              this.flowModel = {}
            }
            this.initProcessForm(data);
            this.flowName = flowName
            this.flowKey = flowKey
            resolve()
          }
        }).catch(e => {
        })
      })
    },
    saveFlow () {
      const graphData = this.lf.getGraphData()
      saveFlow({
        caller: "testCaller",
        flowModel: JSON.stringify(graphData),
        flowModuleId: this.flowModuleId,
        tenant: "testTenant",
      }).then(() => {
        this.$message({
          showClose: true,
          message: '保存成功',
          type: 'success',
        })
      })
    },
    publishFlow () {
      deployFlow({
        caller: "testCaller",
        flowModuleId: this.flowModuleId,
        tenant: "testTenant",
      }).then(({ errMsg, errCode }) => {
        if (errCode !== 1000) {
          this.$message({
            showClose: true,
            message: errMsg,
            type: 'error',
          })
        } else {
          this.$message({
            showClose: true,
            message: '发布成功',
            type: 'success',
          })
        }
      })
    },
    getData () {
      this.openDrawer = true
      this.drawType = 'graphData'
      this.graphData = JSON.stringify(this.lf.getGraphData())
    },
    saveCondition () {
      this.lf.setProperties(this.activeData.id, this.activeData.properties)
      this.openDrawer = false
    },
    /*snakerflow*/
    handleClose () {
      this.dialogVisible = false
      this.$refs.dialogComponent.handleClose()
      if (this.dialogType === 'DataDetail' && this.clipboard) {
        this.clipboard.destroy()
      }
    },
    handleOpened () {
      if (this.dialogType === 'DataDetail') {
        const copyEl = document.querySelectorAll('.m-btn-copy')
        this.clipboard = new Clipboard(copyEl, {
          container: document.querySelector('.m-dialog-data-detail')
        })
        this.clipboard.on('success', function (e) {
          Message.success('复制成功')
          e.clearSelection()
        })
        this.clipboard.on('error', function (e) {
          Message.error('复制失败')
        })
      }
    },
    /**
     * 初始化流程定义表单信息
     */
    initProcessForm (data) {
      this.$set(this.processForm, 'type', 'bpmn:process')
      this.$set(this.processForm, 'id', data.flowModuleId)
      this.$set(this.processForm, 'displayName', data.flowName)
      this.$set(this.processForm, 'expireTime', data.expireTime)
      this.$set(this.processForm, 'instanceUrl', data.instanceUrl)
      this.$set(this.processForm, 'instanceNoClass', data.instanceNoClass)
    },
  },
  components: {
    PropertySetting,
    Toolbar
  }
}
</script>

<template>
  <div class="flow-chart">
    <toolbar
      class="node-red-toolbar"
      @saveFlow="saveFlow"
      @publishFlow="publishFlow"
      @getData="getData"
      :flowName="flowName"
      :flowKey="flowKey"
    >
    </toolbar>
    <div ref="container" class="container"></div>
    <el-drawer
      v-model="openDrawer"
      title="查看"
    >
      <div v-if="drawType === 'edgeCondition'">
        <span>判断条件</span>
        <el-input
          v-model="activeData.properties.conditionsequenceflow"
          :rows="2"
          type="textarea"
          placeholder="请输入条件判断表达式"
        />
        <el-button @click="saveCondition">确认</el-button>
      </div>
      <div v-if="drawType === 'graphData'">
        <span>流程图数据</span>
        <el-input
          v-model="graphData"
          :rows="20"
          type="textarea"
          placeholder="请输入条件判断表达式"
        />
      </div>
    </el-drawer>


  <div class="m-snakerflow-designer">
    <div id="LF-view"></div>
    <PropertySetting ref="propertySetting" :extendAttrConfig="extendAttrConfig" :node="nodeClick" v-model="processForm" :lf="lf"/>
<el-dialog
      custom-class="m-dialog-data-detail"
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      destroy-on-close
      width="60%"
      @opened="handleOpened"
      :append-to-body="true"
      :before-close="handleClose">
      <component :is="dialogType" :graphData="graphData" ref="dialogComponent"></component>
      <span slot="footer" class="dialog-footer" v-if="dialogType=='ImportData' || dialogType=='HighLightData'">
            <el-button @click="handleClose">取 消</el-button>
            <el-button type="primary" @click="handleSubmit">确 定</el-button>
            <el-dropdown placement="top" trigger="click" style="float: left;" v-if="localStorageLfData.length" @command="handleCommand">
              <el-button type="text">选择<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i></el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item :key="item.value" v-for="item in localStorageLfData" :command="item.value">
                  {{item.label}}&nbsp;&nbsp;<i class="el-icon-remove" @click="handleRemove(item.value)"></i>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
        </span>
<!--      <span slot="footer" class="dialog-footer" v-if="dialogType=='DataDetail'">
            <el-button type="primary" class="m-btn-copy" :data-clipboard-text="copyJsonContent">复制JSON</el-button>
            <el-button type="primary" class="m-btn-copy" :data-clipboard-text="copyXmlContent">复制XML</el-button>
      </span>-->
    </el-dialog>
  </div>
</div>
</template>

<style scoped>
.container {
  width: 100%;
  height: 100%;
}
.flow-chart {
  position: relative;
  width: 100%;
  height: 600px;
}

.flow-chart-palette {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
}
.node-red-toolbar {
  position: absolute;
  width: 100%;
  left: 0;
  top: 0;
  z-index: 1;
  background: #fbfbfb;
}
::v-deep .lf-dndpanel {
  top: 30px;
}
/*snakerflow*/
.m-snakerflow-designer {
  height: 100%;
  position: relative;
}
#LF-view{
  width: 100%;
  height: 100%;
  outline: none;
}
.m-snaker-flow-designer >>> #LF-view {
  width: 100%;
  height: 100%;
  margin-left: 0;
}
</style>
